// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <Python.h>

#include <ViewerProxy.h>
#include <ViewerRPC.h>
#include <PlotPluginManager.h>
#include <PlotPluginInfo.h>
#include <OperatorPluginManager.h>
#include <OperatorPluginInfo.h>
#include <DebugStream.h>
#include <StringHelpers.h>
#include <TimingsManager.h>
#include <visit-config.h>

#include <PyAnnotationAttributes.h>
#include <PyConstructDataBinningAttributes.h>
#include <PyExportDBAttributes.h>
#include <PyDBOptionsAttributes.h>
#include <PyGlobalLineoutAttributes.h>
#include <PyImageObject.h>
#include <PyInteractorAttributes.h>
#include <PyKeyframeAttributes.h>
#include <PyLaunchProfile.h>
#include <PyLegendAttributesObject.h>
#include <PyLightAttributes.h>
#include <PyLineObject.h>
#include <PyLine3DObject.h>
#include <PyMachineProfile.h>
#include <PyMaterialAttributes.h>
#include <PyMeshManagementAttributes.h>
#include <PyPickAttributes.h>
#include <PyPrinterAttributes.h>
#include <PyProcessAttributes.h>
#include <PyRenderingAttributes.h>
#include <PySaveWindowAttributes.h>
#include <PySILRestriction.h>
#include <PyText2DObject.h>
#include <PyText3DObject.h>
#include <PyTimeSliderObject.h>
#include <PyQueryOverTimeAttributes.h>
#include <PyViewAxisArrayAttributes.h>
#include <PyViewCurveAttributes.h>
#include <PyView2DAttributes.h>
#include <PyView3DAttributes.h>
#include <PyWindowInformation.h>

#include <avtSILRestriction.h>
#include <avtSILRestrictionTraverser.h>

#include <AnimationAttributes.h>
#include <AnnotationObject.h>
#include <AnnotationObjectList.h>
#include <Expression.h>
#include <ExpressionList.h>
#include <GlobalAttributes.h>
#include <LightAttributes.h>
#include <LightList.h>
#include <Plot.h>
#include <PlotList.h>
#include <WindowInformation.h>

#include <string>

#define SLEN 5000

//
// Extern data
//
extern ViewerProxy *viewer;
extern bool localNameSpace;

//
// Static data
//
static std::string  macroString;
static bool         macroRecord = false;
static FILE        *logFile = NULL;
static bool         logging = false;
static int          logLevel = 0;

//
// Macro functions
//

void
Macro_SetString(const std::string &s)
{
    macroString = s;
}

const std::string &
Macro_GetString()
{
    return macroString;
}

void
Macro_SetRecord(bool val)
{
    macroRecord = val;
}

bool
Macro_GetRecord()
{
    return macroRecord;
}

//
// Log file functions
//

bool
LogFile_Open(const char *filename)
{
    logging = true;
    logFile = fopen(filename, "wb");
    if(logFile)
    {
        fprintf(logFile, "# Visit %s log file\n", VISIT_VERSION);
        fprintf(logFile, "ScriptVersion = \"%s\"\n", VISIT_VERSION);
        fprintf(logFile, "if ScriptVersion != Version():\n");
        fprintf(logFile, "    print \"This script is for VisIt %%s. "
                "It may not work with version %%s\" %% "
                "(ScriptVersion, Version())\n");
    }

    return logging;
}

void
LogFile_Close()
{
    if(logFile)
        fclose(logFile);
}

void
LogFile_SetEnabled(bool val)
{
    logging = val;
}

bool
LogFile_GetEnabled()
{
    return logging;
}

void
LogFile_IncreaseLevel()
{
    ++logLevel;
}

void
LogFile_DecreaseLevel()
{
    --logLevel;
    if(logLevel < 0)
       logLevel = 0;
}

void
LogFile_Write(const char *str)
{
    if(logging && logLevel == 0)
    {
        // Add the string to the macro string
        if(macroRecord)
            macroString += str;

        // Write to the log
        if(logFile != NULL)
            fprintf(logFile, "%s", str);
    }
}

static std::string visitmodule()
{
    std::string s;
    if(!localNameSpace)
        s = std::string("visit.");
    return s;
}

static std::string constructor(const std::string &s)
{
    std::string::size_type pos = s.find(" = ");
    if(pos == std::string::npos)
        return s;
    return s.substr(0, pos + 3) + visitmodule() + s.substr(pos+3);
}

static std::string EscapeFilename(const std::string &s)
{
#if defined(_WIN32)
    // Replace single backslash with double backslash
    std::string s2(StringHelpers::Replace(s, "\\", "\\\\"));
    // If we ended up adding in 4 backslashes, change back to 2.
    return StringHelpers::Replace(s2, "\\\\\\\\", "\\\\");
#else
    return s;
#endif
}

// ****************************************************************************
//
// State Logging functions
//
// Purpose: The purpose of the log functions is to turn ViewerRPC information
//          into valid Python code for the VisIt module that can be logged or
//          recorded into a macro.
//
// Note:    The logging functions take ViewerRPC data, whose important fields,
//          vary depending on the RPC being executed, and use that data to
//          create the Python code returned in the "str" string. The exact
//          usage of the ViewerRPC fields for a given RPC must match the
//          usage in ViewerProxy.C in order for the logging functions to remain
//          accurate.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jan 10 11:50:15 PDT 2006
//
// Modifications:
//   Brad Whitlock, Wed Mar 8 17:05:11 PST 2006
//   Added RedoView.
//
//   Jeremy Meredith, Wed Feb  3 15:35:08 EST 2010
//   Removed maintain data; moved maintain view from Global settings
//   (Main window) to per-window Window Information (View window).
//
// ****************************************************************************

#define MSG_NOT_IMPLEMENTED 0
#define MSG_UNSUPPORTED     1

static std::string MESSAGE_COMMENT(const char *name, int reason)
{
    std::string s;

    if(reason == MSG_NOT_IMPLEMENTED)
    {
        s = (std::string("# Logging for ") + name) + " is not implemented yet.\n";
    }
    else if(reason == MSG_UNSUPPORTED)
    {
        s = (std::string("# The ") + name) + " RPC is not supported in the VisIt module "
                 "so it will not be logged.\n";
    }
    return s;
}


static std::string log_AddWindowRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("AddWindow()\n");
}

static std::string log_DeleteWindowRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("DeleteWindow()\n");
}

static std::string log_SetWindowLayoutRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetWindowLayout(%d)\n", rpc->GetWindowLayout());
    return visitmodule() + std::string(str);
}

static std::string log_SetActiveWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetActiveWindow(%d)\n", rpc->GetWindowId());
    return visitmodule() + std::string(str);
}

static std::string log_ClearWindowRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ClearWindow()\n");
}

static std::string log_ClearAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ClearAllWindows()\n");
}

static std::string log_OpenDatabaseRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "OpenDatabase(\"%s\", %d)\n",
             EscapeFilename(rpc->GetDatabase()).c_str(),
             rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_CloseDatabaseRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "OpenDatabase(\"%s\")\n",
             EscapeFilename(rpc->GetDatabase()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_ActivateDatabaseRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "ActivateDatabase(\"%s\")\n",
             EscapeFilename(rpc->GetDatabase()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_CheckForNewStatesRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "CheckForNewStates(\"%s\")\n",
             EscapeFilename(rpc->GetDatabase()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_CreateDatabaseCorrelationRPC(ViewerRPC *rpc)
{
    std::string q("\"");
    char str[SLEN];
    std::string s("CreateDatabaseCorrelation(\"");
    s += EscapeFilename(rpc->GetDatabase());
    s += "\",(";
    const stringVector &dbs = rpc->GetProgramOptions();
    for(unsigned int i = 0; i < dbs.size(); ++i)
    {
        s += (q + EscapeFilename(dbs[i]) + q);
        if(i < dbs.size() - 1)
            s += ", ";
    }
    snprintf(str, SLEN, "%s), %d)\n", s.c_str(), rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_AlterDatabaseCorrelationRPC(ViewerRPC *rpc)
{
     char str[SLEN];
     std::string s("AlterDatabaseCorrelation(\"");
     s += EscapeFilename(rpc->GetDatabase());
     s += "\",(";
     const stringVector &dbs = rpc->GetProgramOptions();
     for(unsigned int i = 0; i < dbs.size(); ++i)
     {
         s += EscapeFilename(dbs[i]);
         if(i < dbs.size() - 1)
             s += ", ";
     }
     snprintf(str, SLEN, "%s), %d)\n", s.c_str(), rpc->GetIntArg1());
     return visitmodule() + std::string(str);
}

static std::string log_DeleteDatabaseCorrelationRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "DeleteDatabaseCorrelation(\"%s\")\n",
             EscapeFilename(rpc->GetDatabase()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_ReOpenDatabaseRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "OpenDatabase(\"%s\", %d)\n",
             EscapeFilename(rpc->GetDatabase()).c_str(),
             rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_ReplaceDatabaseRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "ReplaceDatabase(\"%s\", %d)\n",
             EscapeFilename(rpc->GetDatabase()).c_str(),
             rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_OverlayDatabaseRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "OverlayDatabase(\"%s\")\n",
             EscapeFilename(rpc->GetDatabase()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_OpenComponentHelper(ViewerRPC *rpc, const char *mName)
{
    const stringVector &argv = rpc->GetProgramOptions();
    char str[SLEN];

    if(argv.size() == 0)
    {
        snprintf(str, SLEN, "%s%s(\"%s\")\n",
                 visitmodule().c_str(), mName, rpc->GetProgramHost().c_str());
    }
    else if(argv.size() == 1)
    {
        snprintf(str, SLEN, "%s%s(\"%s\", \"%s\")\n",
                visitmodule().c_str(), mName, rpc->GetProgramHost().c_str(), argv[0].c_str());
    }
    else
    {
        std::string tmp("launchArguments = (");
        for(unsigned int i = 0; i < argv.size(); ++i)
        {
            tmp += "\"";
            tmp += argv[i];
            tmp += "\"";
            if(i < argv.size() - 1)
                tmp += ", ";
        }
        tmp += ")\n";
        snprintf(str, SLEN, "%s%s%s(\"%s\", launchArguments)\n",
                 tmp.c_str(), visitmodule().c_str(), mName, rpc->GetProgramHost().c_str());
    }
    return std::string(str);
}

static std::string log_OpenComputeEngineRPC(ViewerRPC *rpc)
{
    return log_OpenComponentHelper(rpc, "OpenComputeEngine");
}

static std::string log_OpenMDServerRPC(ViewerRPC *rpc)
{
    return log_OpenComponentHelper(rpc, "OpenMDServer");
}

static std::string log_CloseComputeEngineRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "CloseComputeEngine(\"%s\", \"%s\")\n",
             rpc->GetProgramHost().c_str(),
             rpc->GetProgramSim().c_str());
    return visitmodule() + std::string(str);
}

static std::string log_AnimationSetNFramesRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "AnimationSetNFrames(%d)\n", rpc->GetNFrames());
    return visitmodule() + std::string(str);
}

static std::string log_AnimationPlayRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("AnimationPlay", MSG_UNSUPPORTED);
}

static std::string log_AnimationReversePlayRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("AnimationReversePlay", MSG_UNSUPPORTED);
}

static std::string log_AnimationStopRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("AnimationStop", MSG_UNSUPPORTED);
}

static std::string log_TimeSliderNextStateRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("TimeSliderNextState()\n");
}

static std::string log_TimeSliderPreviousStateRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("TimeSliderPreviousState()\n");
}

static std::string log_SetTimeSliderStateRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetTimeSliderState(%d)\n", rpc->GetStateNumber());
    return visitmodule() + std::string(str);
}

static std::string log_SetActiveTimeSliderRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetActiveTimeSlider(\"%s\")\n",
             EscapeFilename(rpc->GetDatabase()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_AddPlotRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    std::string plotName("?");
    PlotPluginManager *pluginManager = viewer->GetPlotPluginManager();
    std::string id(pluginManager->GetEnabledID(rpc->GetPlotType()));
    ScriptingPlotPluginInfo *info = pluginManager->
        GetScriptingPluginInfo(id);
    if(info != 0)
        plotName = info->GetName();

    int  inheritSILRestriction = viewer->GetViewerState()->GetGlobalAttributes()->GetNewPlotsInheritSILRestriction();
    int  applyOperator = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1: 0;
    snprintf(str, SLEN, "AddPlot(\"%s\", \"%s\", %d, %d)\n",
             plotName.c_str(),
             rpc->GetVariable().c_str(),
             inheritSILRestriction,
             applyOperator);
    return visitmodule() + std::string(str);
}

static std::string log_SetPlotFrameRangeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetPlotFrameRange(%d, %d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3());
    return visitmodule() + std::string(str);
}

static std::string log_DeletePlotKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "DeletePlotKeyframe(%d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2());
    return visitmodule() + std::string(str);
}

static std::string log_MovePlotKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MovePlotKeyframe(%d, %d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3());
    return visitmodule() + std::string(str);
}

static std::string log_DeleteActivePlotsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("DeleteActivePlots()\n");
}

static std::string log_HideActivePlotsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("HideActivePlots()\n");
}

static std::string log_DrawPlotsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("DrawPlots()\n");
}

static std::string log_DisableRedrawRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("DisableRedraw()\n");
}

static std::string log_RedrawRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("RedrawWindow()\n");
}

static std::string log_SetActivePlotsRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int slen = SLEN;
    const intVector &ids = rpc->GetActivePlotIds();
    char *sptr = str;
    int L = snprintf(sptr, slen, "SetActivePlots(");
    sptr += L, slen -= L;
    if(ids.size() > 1)
    {
        L = snprintf(sptr, slen, "(");
        sptr += L, slen -= L;
    }
    for(unsigned int i = 0; i < ids.size(); ++i)
    {
        L = snprintf(sptr, slen, "%d", ids[i]);
        sptr += L, slen -= L;
        if(i < ids.size() - 1)
        {
            L = snprintf(sptr, slen, ", ");
            sptr += L, slen -= L;
        }
    }
    if(ids.size() > 1)
    {
        L = snprintf(sptr, slen, ")");
        sptr += L, slen -= L;
    }
    snprintf(sptr, slen, ")\n");
    return visitmodule() + std::string(str);
}

static std::string log_ChangeActivePlotsVarRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "ChangeActivePlotsVar(\"%s\")\n",
             rpc->GetVariable().c_str());
    return visitmodule() + std::string(str);
}

static std::string log_AddOperatorRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    std::string operatorName("?");
    OperatorPluginManager *pluginManager = viewer->GetOperatorPluginManager();
    std::string id(pluginManager->GetEnabledID(rpc->GetOperatorType()));
    ScriptingOperatorPluginInfo *info = pluginManager->
        GetScriptingPluginInfo(id);
    if(info != 0)
        operatorName = info->GetName();

    int applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1 : 0;
    snprintf(str, SLEN, "AddOperator(\"%s\", %d)\n",
             operatorName.c_str(),
             applyAll);
    return visitmodule() + std::string(str);
}

static std::string log_DeleteOperatorKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "DeleteOperatorKeyframe(%d, %d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3());
    return visitmodule() + std::string(str);
}

static std::string log_MoveOperatorKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MoveOperatorKeyframe(%d, %d, %d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3(), rpc->GetIntArg4());
    return visitmodule() + std::string(str);
}

static std::string log_PromoteOperatorRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1 : 0;
    snprintf(str, SLEN, "PromoteOperator(%d, %d)\n", rpc->GetOperatorType(),
             applyAll);
    return visitmodule() + std::string(str);
}

static std::string log_DemoteOperatorRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1 : 0;
    snprintf(str, SLEN, "DemoteOperator(%d, %d)\n", rpc->GetOperatorType(),
             applyAll);
    return visitmodule() + std::string(str);
}

static std::string log_RemoveOperatorRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1 : 0;
    snprintf(str, SLEN, "RemoveOperator(%d, %d)\n", rpc->GetOperatorType(),
             applyAll);
    return visitmodule() + std::string(str);
}

static std::string log_RemoveLastOperatorRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1 : 0;
    snprintf(str, SLEN, "RemoveLastOperator(%d)\n", applyAll);
    return visitmodule() + std::string(str);
}

static std::string log_RemoveAllOperatorsRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1 : 0;
    snprintf(str, SLEN, "RemoveAllOperators(%d)\n", applyAll);
    return visitmodule() + std::string(str);
}

static std::string log_SaveWindowRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PySaveWindowAttributes_GetLogString()));
    s += visitmodule() + "SetSaveWindowAttributes(SaveWindowAtts)\n";
    s += visitmodule() + "SaveWindow()\n";
    return s;
}

static void log_SetPlotOptionsHelper(ViewerRPC *rpc, std::string &atts,
    std::string &plotName)
{
    PlotPluginManager *pluginManager = viewer->GetPlotPluginManager();
    std::string id(pluginManager->GetEnabledID(rpc->GetPlotType()));
    ScriptingPlotPluginInfo *info = pluginManager->
        GetScriptingPluginInfo(id);
    if(info != 0)
    {
        char *s = info->GetLogString();
        atts = constructor(s);
        delete [] s;
        plotName = info->GetName();
        plotName += "Atts";
    }
}

static std::string log_SetDefaultPlotOptionsRPC(ViewerRPC *rpc)
{
    std::string atts(""), plotName("");
    log_SetPlotOptionsHelper(rpc, atts, plotName);
    atts += visitmodule() + "SetDefaultPlotOptions(";
    atts += plotName;
    atts += ")\n";
    return atts;
}

static std::string log_SetPlotOptionsRPC(ViewerRPC *rpc)
{
    std::string atts(""), plotName("");
    log_SetPlotOptionsHelper(rpc, atts, plotName);
    atts += visitmodule() + "SetPlotOptions(";
    atts += plotName;
    atts += ")\n";
    return atts;
}

static void log_SetOperatorOptionsHelper(ViewerRPC *rpc, std::string &atts,
    std::string &operatorName)
{
    OperatorPluginManager *pluginManager = viewer->GetOperatorPluginManager();
    std::string id(pluginManager->GetEnabledID(rpc->GetOperatorType()));
    ScriptingOperatorPluginInfo *info = pluginManager->
        GetScriptingPluginInfo(id);
    if(info != 0)
    {
        char *s = info->GetLogString();
        atts = constructor(s);
        delete [] s;
        operatorName = info->GetName();
        operatorName += "Atts";
    }
}

static std::string log_SetDefaultOperatorOptionsRPC(ViewerRPC *rpc)
{
    std::string atts(""), operatorName("");
    log_SetOperatorOptionsHelper(rpc, atts, operatorName);
    atts += visitmodule() + "SetDefaultOperatorOptions(";
    atts += operatorName;
    atts += ")\n";
    return atts;
}


// ****************************************************************************
//
// Modifications:
//   Kathleen Biagas, Thu Feb 28 10:21:40 PST 2019
//   Look up the active operator index, as it should be the second argument
//   to SetOperatorOptions. Fixes #3273.
//
// ****************************************************************************

static std::string log_SetOperatorOptionsRPC(ViewerRPC *rpc)
{
    std::string atts(""), operatorName("");
    bool  applyOperator = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator();
    log_SetOperatorOptionsHelper(rpc, atts, operatorName);
    int activeOperator = -1;
    PlotList *plotList = viewer->GetViewerState()->GetPlotList();
    for (int i = 0; i < plotList->GetNumPlots() && -1==activeOperator; ++i)
    {
        const Plot &current = plotList->operator[](i);
        if(current.GetActiveFlag())
            activeOperator = current.GetActiveOperator();
    }
    atts += visitmodule() + "SetOperatorOptions(";
    atts += operatorName;
    atts += ", ";
    atts+= std::to_string(activeOperator);
    atts += ", ";
    atts += (applyOperator ? "1" : "0");
    atts += ")\n";
    return atts;
}

static std::string log_AddInitializedOperatorRPC(ViewerRPC *rpc)
{
    std::string s;
    s = log_AddOperatorRPC(rpc);
    s += log_SetOperatorOptionsRPC(rpc);
    return s;
}

static std::string log_WriteConfigFileRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("WriteConfigFile()\n");
}

static std::string log_IconifyAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("IconifyAllWindows()\n");
}

static std::string log_DeIconifyAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("DeIconifyAllWindows()\n");
}

static std::string log_ShowAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ShowAllWindows()\n");
}

static std::string log_HideAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("HideAllWindows()\n");
}

static std::string log_SetAnnotationAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyAnnotationAttributes_GetLogString()));
    s += std::string("SetAnnotationAttributes(AnnotationAtts)\n");
    return visitmodule() + s;
}

static std::string log_SetDefaultAnnotationAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyAnnotationAttributes_GetLogString()));
    s += std::string("SetDefaultAnnotationAttributes(AnnotationAtts)\n");
    return visitmodule() + s;
}

static std::string log_ResetAnnotationAttributesRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("ResetAnnotationAttributes", MSG_UNSUPPORTED);
}

static std::string log_SetKeyframeAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyKeyframeAttributes_GetLogString()));
    s += std::string("SetKeyframeAttributes(KeyframeAtts)\n");
    return visitmodule() + s;
}

// ****************************************************************************
// Method: log_SetPlotSILRestrictionRPC
//
// Purpose:
//   Logs changes to the SIL restriction.
//
// Programmer: Brad Whitlock
// Creation:   Wed Jan 11 09:55:18 PDT 2006
//
// Modifications:
//   Brad Whitlock, Wed Jan 11 09:55:42 PDT 2006
//   I removed a call to the SIL traverser's UsesAllData method because it
//   was causing a crash sometimes.
//
//   Hank Childs, Mon Dec 14 13:12:58 PST 2009
//   Reverse ordering for two conditions in an if test.  One is cheap, the
//   other expensive.  By reversing them, the overall time is much faster
//   (because of short circuiting).
//
// ****************************************************************************

static std::string log_SetPlotSILRestrictionRPC(ViewerRPC *rpc)
{
    int t1 = visitTimer->StartTimer();
    std::string s("silr = " + visitmodule() + "SILRestriction()\n");
    int nsets[2] = {0,0};
    avtSILRestriction_p restriction = viewer->GetPlotSILRestriction();
    avtSILRestrictionTraverser trav(restriction);
    int setid;
    for(setid = 0; setid < restriction->GetNumSets(); ++setid)
    {
        nsets[trav.UsesData(setid)?1:0]++;
    }

    if(nsets[1] == restriction->GetNumSets())
    {
        s += "silr.TurnOnAll()\n";
    }
    else if(nsets[0] < nsets[1])
    {
        // More sets were on so we'll turn them all on and then turn off sets
        // that were off.
        intVector sets;
        for(setid = 0; setid < restriction->GetNumSets(); ++setid)
        {
            if(!trav.UsesData(setid) &&
               restriction->GetSILSet(setid)->GetMapsOut().size() == 0)
            {
                sets.push_back(setid);
            }
        }

        if(sets.size() == 0)
        {
            s += "silr.TurnOffAll()\n";
        }
        else if(sets.size() == 1)
        {
            s += "silr.TurnOnAll()\n";
            char tmp[20];
            snprintf(tmp, 20, "silr.TurnOffSet(%d)\n", sets[0]);
            s += tmp;
        }
        else
        {
            s += "silr.SuspendCorrectnessChecking()\n";
            s += "silr.TurnOnAll()\n";
            s += "for silSet in (";
            for(unsigned int i = 0; i < sets.size(); ++i)
            {
                char tmp[20];
                if(i < sets.size() - 1)
                    snprintf(tmp, 20, "%d,", sets[i]);
                else
                    snprintf(tmp, 20, "%d", sets[i]);
                s += tmp;
            }
            s += "):\n";
            s += "    silr.TurnOffSet(silSet)\n";
            s += "silr.EnableCorrectnessChecking()\n";
       }
    }
    else
    {
        // More sets were off so we'll turn them all off and then turn on sets
        // that were on.
        intVector sets;
        for(setid = 0; setid < restriction->GetNumSets(); ++setid)
        {
            if(trav.UsesData(setid) &&
               restriction->GetSILSet(setid)->GetMapsOut().size() == 0)
            {
                sets.push_back(setid);
            }
        }

        if(sets.size() == 0)
        {
            s += "silr.TurnOffAll()\n";
        }
        else if(sets.size() == 1)
        {
            s += "silr.TurnOffAll()\n";
            char tmp[20];
            snprintf(tmp, 20, "silr.TurnOnSet(%d)\n", sets[0]);
            s += tmp;
        }
        else
        {
            s += "silr.SuspendCorrectnessChecking()\n";
            s += "silr.TurnOffAll()\n";
            s += "for silSet in (";
            for(unsigned int i = 0; i < sets.size(); ++i)
            {
                char tmp[20];
                if(i < sets.size() - 1)
                    snprintf(tmp, 20, "%d,", sets[i]);
                else
                    snprintf(tmp, 20, "%d", sets[i]);
                s += tmp;
            }
            s += "):\n";
            s += "    silr.TurnOnSet(silSet)\n";
            s += "silr.EnableCorrectnessChecking()\n";
        }
    }
    bool applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplySelection();
    s += visitmodule() + "SetPlotSILRestriction(silr ,";
    s += (applyAll ? "1" : "0");
    s += ")\n";
    visitTimer->StopTimer(t1, "Setting up log string for sil restrictions");
    return s;
}

static std::string log_SetViewAxisArrayRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyViewAxisArrayAttributes_GetLogString()));
    s += visitmodule() + std::string("SetViewAxisArray(ViewAxisArrayAtts)\n");
    return s;
}

static std::string log_SetViewCurveRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyViewCurveAttributes_GetLogString()));
    s += visitmodule() + std::string("SetViewCurve(ViewCurveAtts)\n");
    return s;
}

static std::string log_SetView2DRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyView2DAttributes_GetLogString()));
    s += visitmodule() + std::string("SetView2D(View2DAtts)\n");
    return s;
}

static std::string log_SetView3DRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyView3DAttributes_GetLogString()));
    s += visitmodule() + std::string("SetView3D(View3DAtts)\n");
    return s;
}

static std::string log_ResetPlotOptionsRPC(ViewerRPC *rpc)
{
    std::string plotName("?");
    PlotPluginManager *pluginManager = viewer->GetPlotPluginManager();
    std::string id(pluginManager->GetEnabledID(rpc->GetPlotType()));
    ScriptingPlotPluginInfo *info = pluginManager->
        GetScriptingPluginInfo(id);
    if(info != 0)
        plotName = info->GetName();

    return visitmodule() + std::string("ResetPlotOptions(\"") + plotName + std::string("\")\n");
}

static std::string log_ResetOperatorOptionsRPC(ViewerRPC *rpc)
{
    std::string operatorName("?");
    OperatorPluginManager *pluginManager = viewer->GetOperatorPluginManager();
    std::string id(pluginManager->GetEnabledID(rpc->GetOperatorType()));
    ScriptingOperatorPluginInfo *info = pluginManager->
        GetScriptingPluginInfo(id);
    if(info != 0)
        operatorName = info->GetName();

    int  applyAll = viewer->GetViewerState()->GetGlobalAttributes()->GetApplyOperator() ? 1: 0;
    char tmp[20];
    snprintf(tmp, 20, "\", %d)\n", applyAll);
    return visitmodule() + std::string("ResetOperatorOptions(\"") + operatorName + std::string(tmp);
}

static std::string log_SetAppearanceRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("SetAppearance", MSG_UNSUPPORTED);
}

//*****************************************************************************
//  Modifications:
//    Kathleen Bonnell, Thu Aug  3 09:25:00 PDT 2006
//    Added CurveMeshVar
//
//*****************************************************************************

static std::string log_ProcessExpressionsRPC(ViewerRPC *rpc)
{
    std::string exprList("");
    char str[SLEN];

    ExpressionList *list = viewer->GetViewerState()->GetExpressionList();
    for(int i = 0; i < list->GetNumExpressions(); ++i)
    {
        const Expression &expr = list->GetExpressions(i);
        if(expr.GetFromDB())
            continue;

        const char *fx = 0;
        if(expr.GetType() == Expression::ScalarMeshVar)
            fx = "DefineScalarExpression";
        else if(expr.GetType() == Expression::VectorMeshVar)
            fx = "DefineVectorExpression";
        else if(expr.GetType() == Expression::TensorMeshVar)
            fx = "DefineTensorExpression";
        else if(expr.GetType() == Expression::ArrayMeshVar)
            fx = "DefineArrayExpression";
        else if(expr.GetType() == Expression::CurveMeshVar)
            fx = "DefineCurveExpression";
        else if(expr.GetType() == Expression::Mesh)
            fx = "DefineMeshExpression";
        else if(expr.GetType() == Expression::Material)
            fx = "DefineMaterialExpression";
        else if(expr.GetType() == Expression::Species)
            fx = "DefineSpeciesExpression";

        if(fx != 0)
        {
            std::string def(expr.GetDefinition());
            if(def.size() > 0 && def[def.size()-1] == '\n')
                def = def.substr(0, def.size()-1);
            snprintf(str, SLEN, "%s%s(\"%s\", \"%s\")\n", visitmodule().c_str(), fx, expr.GetName().c_str(),
                     def.c_str());
            exprList += str;
        }
    }

    return exprList;
}

//*****************************************************************************
//  Modifications:
//    Brad Whitlock, Tue May 8 10:52:04 PDT 2007
//    Fixed so the prefixes have dots.
//
//*****************************************************************************


static std::string log_SetLightListRPC(ViewerRPC *rpc)
{
    std::string s;
    LightList *lightlist = viewer->GetViewerState()->GetLightList();
    for(int i = 0; i < lightlist->NumLights(); ++i)
    {
        char objName[20], objNameDot[20], index[20];
        snprintf(objName, 20, "light%d", i);
        snprintf(objNameDot, 20, "light%d.", i);
        snprintf(index, 20, "%d", i);

        LightAttributes L(lightlist->GetLight(i));
        s += objName;
        s += " = " + visitmodule() + "LightAttributes()\n";
        s += PyLightAttributes_ToString(&L, objNameDot);
        s += visitmodule() + "SetLight(";
        s += index;
        s += ", ";
        s += objName;
        s += ")\n";
    }
    return s;
}

static std::string log_SetDefaultLightListRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("SetDefaultLightList", MSG_UNSUPPORTED);
}

static std::string log_ResetLightListRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("ResetLightList", MSG_UNSUPPORTED);
}

static std::string log_SetAnimationAttributesRPC(ViewerRPC *rpc)
{
    // Note - there's no function to set all of the annotation atts at the same
    //        so we're just setting the animation timeout for now.
    AnimationAttributes *atts = viewer->GetViewerState()->GetAnimationAttributes();
    char str[SLEN];
    snprintf(str, SLEN, "SetAnimationTimeout(%d)\n", atts->GetTimeout());
    return visitmodule() + std::string(str);
}

static std::string log_SetWindowAreaRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    int w,h,x,y;
    sscanf(rpc->GetWindowArea().c_str(), "%dx%d+%d+%d", &w, &h, &x, &y);
    snprintf(str, SLEN, "SetWindowArea(%d, %d ,%d, %d)\n", w,h,x,y);
    return visitmodule() + std::string(str);
}

static std::string log_PrintWindowRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("PrintWindow()\n");
}

static std::string log_ResetViewRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ResetView()\n");
}

static std::string log_RecenterViewRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("RecenterView()\n");
}

static std::string log_ToggleMaintainViewModeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleMaintainViewMode()\n");
}

static std::string log_ToggleBoundingBoxModeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleBoundingBoxMode()\n");
}

static std::string log_ToggleCameraViewModeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleCameraViewMode()\n");
}

static std::string log_TogglePerspectiveViewRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("TogglePerspectiveView()\n");
}

static std::string log_ToggleSpinModeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleSpinMode()\n");
}

static std::string log_ToggleLockTimeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleLockTime()\n");
}

static std::string log_ToggleLockToolsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleLockTools()\n");
}

static std::string log_ToggleLockViewModeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleLockViewMode()\n");
}

static std::string log_ToggleFullFrameRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ToggleFullFrameMode()\n");
}

static std::string log_UndoViewRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("UndoView()\n");
}

static std::string log_RedoViewRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("RedoView()\n");
}

static std::string log_InvertBackgroundRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("InvertBackgroundColor()\n");
}

static std::string log_ClearPickPointsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ClearPickPoints()\n");
}

static std::string log_RemovePicksRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("RemovePicks()\n");
}

static std::string log_SetWindowModeRPC(ViewerRPC *rpc)
{
    const char *wmodes[] = {"navigate", "zoom", "zone pick", "node pick",
                            "spreadsheet pick", "lineout"};
    return visitmodule() + (std::string("SetWindowMode(\"") + wmodes[rpc->GetWindowMode()]) + "\")\n";
}

static std::string log_EnableToolRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "EnableTool(%d, %d)\n", rpc->GetToolId(),
             rpc->GetBoolFlag());
    return visitmodule() + std::string(str);
}

static std::string log_CopyViewToWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "CopyViewToWindow(%d, %d)\n", rpc->GetWindowLayout(),
             rpc->GetWindowId());
    return visitmodule() + std::string(str);
}

static std::string log_CopyLightingToWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "CopyLightingToWindow(%d, %d)\n", rpc->GetWindowLayout(),
             rpc->GetWindowId());
    return visitmodule() + std::string(str);
}

static std::string log_CopyAnnotationsToWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "CopyAnnotationsToWindow(%d, %d)\n", rpc->GetWindowLayout(),
             rpc->GetWindowId());
    return visitmodule() + std::string(str);
}

static std::string log_CopyPlotsToWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "CopyPlotsToWindow(%d, %d)\n", rpc->GetWindowLayout(),
             rpc->GetWindowId());
    return visitmodule() + std::string(str);
}

static std::string log_ClearCacheRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "ClearCache(\"%s\", \"%s\")\n",
             rpc->GetProgramHost().c_str(),
             rpc->GetProgramSim().c_str());
    return visitmodule() + std::string(str);
}

static std::string log_ClearCacheForAllEnginesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ClearCacheForAllEngines()\n");
}

static std::string log_SetViewExtentsTypeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetViewExtentsType(%d)\n", rpc->GetWindowLayout());
    return visitmodule() + std::string(str);
}

static std::string log_ClearRefLinesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ClearReferenceLines()\n");
}

static std::string log_SetRenderingAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyRenderingAttributes_GetLogString()));
    s += "SetRenderingAttributes(RenderingAtts)\n";
    return visitmodule() + s;
}


//*****************************************************************************
//  Modifications:
//    Kathleen Biagas, Wed Sep  7 12:53:16 PDT 2011
//    Fix pick logging, vars logging.
//
//    Kathleen Biagas, Thu Jan 10 09:06:08 PST 2013
//    Added some type checking.
//
//    Kathleen Biagas, Mon Mar 24 16:24:01 PDT 2014
//    Log time_options for time picks.
//
//*****************************************************************************

static std::string log_QueryRPC(ViewerRPC *rpc)
{
    std::vector<std::string> paramNames;

    MapNode queryParams = rpc->GetQueryParams();
    queryParams.GetEntryNames(paramNames);

    std::string s, qName;
    if (queryParams.HasEntry("query_name"))
       qName = queryParams.GetEntry("query_name")->AsString();
    if (qName.empty())
      return MESSAGE_COMMENT("Query with no name", MSG_UNSUPPORTED);

    if (qName == "Pick")
    {
        std::string pt;
        std::string qn;
        bool timePick = false;
        if (queryParams.HasNumericEntry("do_time"))
            timePick = (bool)queryParams.GetEntry("do_time")->ToBool();
        if (queryParams.HasEntry("pick_type"))
           pt = queryParams.GetEntry("pick_type")->AsString();
        if (pt == "ScreenZone"  || pt == "Zone")
            qn = "ZonePick";
        else if (pt == "ScreenNode" || pt == "Node")
            qn = "NodePick";
        else if (pt == "DomainZone")
        {
            int global = 0;
            if (queryParams.HasNumericEntry("use_global_id"))
                global = queryParams.GetEntry("use_global_id")->ToInt();
            if (global)
                qn = "PickByGlobalZone";
            else
                qn = "PickByZone";
        }
        else if (pt == "DomainNode")
        {
            int global = 0;
            if (queryParams.HasNumericEntry("use_global_id"))
                global = queryParams.GetEntry("use_global_id")->AsInt();
            if (global)
                qn = "PickByGlobalNode";
            else
                qn = "PickByNode";
        }
        else
           return MESSAGE_COMMENT("Pick with no type", MSG_UNSUPPORTED);
        s = qn + "(";
        int numPrinted = 0;
        for (size_t i = 0; i < paramNames.size(); ++i)
        {
            if ((paramNames[i] == "curve_plot_type" ||
                 paramNames[i] == "preserve_coord" ||
                 paramNames[i] == "time_options") &&
                !timePick)
               continue;

            // convert time_options from a dict to its constituent named args
            if (paramNames[i] == "time_options")
            {
                MapNode *t_o = queryParams.GetEntry("time_options");
                stringVector t_o_names;
                t_o->GetEntryNames(t_o_names);
                for (size_t j = 0; j < (size_t)t_o->GetNumEntries(); ++j)
                {
                    if (numPrinted > 0)
                        s += ", ";
                    s += t_o_names[j];
                    s += "=";
                    s += t_o->GetEntry(t_o_names[j])->ConvertToString();
                    numPrinted++;
                }
            }
            else if (paramNames[i] != "query_name" &&
                paramNames[i] != "query_type" &&
                paramNames[i] != "pick_type" &&
                paramNames[i] != "use_global_id" &&
                paramNames[i] != "vars")
            {
                if (numPrinted > 0)
                    s += ", ";
                s += paramNames[i];
                s += "=";
                s += queryParams.GetEntry(paramNames[i])->ConvertToString();
                numPrinted++;
            }
        }
        std::vector<std::string> vars;
        if (queryParams.HasEntry("vars"))
            vars = queryParams.GetEntry("vars")->AsStringVector();
        if (!vars.empty() && !(vars.size() == 1 && vars[0] == "default"))
        {
            if (numPrinted > 0)
                s += ", ";
            s += "vars=";
            s += queryParams.GetEntry("vars")->ConvertToString();
        }
        s += ")\n";
    }
    else
    {
        if (queryParams.HasNumericEntry("do_time") &&
            queryParams.GetEntry("do_time")->ToBool())
            s = "QueryOverTime(\"" + qName + "\"";
        else
            s = "Query(\"" + qName + "\"";

        for (size_t i = 0; i < paramNames.size(); ++i)
        {
            if (paramNames[i] == "use_actual_data")
            {
                if (queryParams.GetEntry(paramNames[i])->ToBool())
                {
                    s += ", ";
                    s += paramNames[i];
                    s += "=";
                    s += queryParams.GetEntry(paramNames[i])->ConvertToString();
                }
            }
            else if (paramNames[i] != "query_name" &&
                     paramNames[i] != "query_type" &&
                     paramNames[i] != "do_time" &&
                     paramNames[i] != "vars")
            {
                s += ", ";
                s += paramNames[i];
                s += "=";
                s += queryParams.GetEntry(paramNames[i])->ConvertToString();
            }
        }
        std::vector<std::string> vars;
        if (queryParams.HasEntry("vars"))
            vars = queryParams.GetEntry("vars")->AsStringVector();
        if (!vars.empty() && !(vars.size() == 1 && vars[0] == "default"))
        {
            s += ", vars=";
            s += queryParams.GetEntry("vars")->ConvertToString();
        }

        s += ")\n";
    }
    return visitmodule() + s;
}

static std::string log_GetQueryParametersRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("GetQueryParameters(\"") + rpc->GetQueryName() + "\")\n";
}


static std::string log_CloneWindowRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("CloneWindow()\n");
}

static std::string log_SetMaterialAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyMaterialAttributes_GetLogString()));
    s += "SetMaterialAttributes(MaterialAtts)\n";
    return visitmodule() + s;
}

static std::string log_SetDefaultMaterialAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyMaterialAttributes_GetLogString()));
    s += "SetDefaultMaterialAttributes(MaterialAtts)\n";
    return visitmodule() + s;
}

static std::string log_ResetMaterialAttributesRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("ResetMaterialAttributes", MSG_UNSUPPORTED);
}

static std::string log_SetPlotDatabaseStateRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetPlotDatabaseState(%d, %d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3());
    return visitmodule() + std::string(str);
}

static std::string log_DeletePlotDatabaseKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "DeletePlotDatabaseKeyframe(%d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2());
    return visitmodule() + std::string(str);
}

static std::string log_MovePlotDatabaseKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MovePlotDatabaseKeyframe(%d, %d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3());
    return visitmodule() + std::string(str);
}

static std::string log_ClearViewKeyframesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ClearViewKeyframes()\n");
}

static std::string log_DeleteViewKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "DeleteViewKeyframe(%d)\n", rpc->GetFrame());
    return visitmodule() + std::string(str);
}

static std::string log_MoveViewKeyframeRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MoveViewKeyframe(%d, %d)\n",
             rpc->GetIntArg1(), rpc->GetIntArg2());
    return visitmodule() + std::string(str);
}

static std::string log_SetViewKeyframeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("SetViewKeyframe()\n");
}

static std::string log_EnableToolbarRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("EnableToolbar", MSG_UNSUPPORTED);
}

static std::string log_HideToolbarsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("HideToolbars()\n");
}

static std::string log_HideToolbarsForAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("HideToolbars(1)\n");
}

static std::string log_ShowToolbarsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ShowToolbars()\n");
}

static std::string log_ShowToolbarsForAllWindowsRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ShowToolbars(1)\n");
}

static std::string log_SetToolbarIconSizeRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("SetToolbarIconSize", MSG_UNSUPPORTED);
}

static std::string log_SaveViewRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("SaveView", MSG_UNSUPPORTED);
}

static std::string log_SetGlobalLineoutAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyGlobalLineoutAttributes_GetLogString()));
    s += "SetGlobalLineoutAttributes(GlobalLineoutAtts)\n";
    return visitmodule() + s;
}

static std::string log_SetPickAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyPickAttributes_GetLogString()));
    s += "SetPickAttributes(PickAtts)\n";
    return visitmodule() + s;
}

static std::string log_ExportColorTableRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("ExportColorTable", MSG_UNSUPPORTED);
}

static std::string log_ExportEntireStateRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SaveSession(\"%s\")\n", EscapeFilename(rpc->GetVariable()).c_str());
    return visitmodule() + std::string(str);
}

static std::string log_ImportEntireStateRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "RestoreSession(\"%s\", %d)\n", EscapeFilename(rpc->GetVariable()).c_str(),
             rpc->GetBoolFlag()?1:0);
    return visitmodule() + std::string(str);
}

static std::string log_ImportEntireStateWithDifferentSourcesRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    std::string stuple;
    const stringVector &sources = rpc->GetProgramOptions();
    stuple = "(";
    for(unsigned int i = 0; i < sources.size(); ++i)
    {
        stuple += std::string("\"") + EscapeFilename(sources[i]) + std::string("\"");
        if(i < sources.size()-1)
            stuple += ",";
    }
    stuple += ")";

    snprintf(str, SLEN, "RestoreSessionWithDifferentSources(\"%s\", %d, %s)\n",
             EscapeFilename(rpc->GetVariable()).c_str(),
             rpc->GetBoolFlag()?1:0,
             stuple.c_str());
    return visitmodule() + std::string(str);
}

static std::string log_ResetPickAttributesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ResetPickAttributes()\n");
}

static std::string log_AddAnnotationObjectRPC(ViewerRPC *rpc)
{
    int annotType = rpc->GetIntArg1();
    // IntArg1 may have been constructed from the 'annotType' and
    // a 'visible' flag.
    // This logic to separate 'annotType' from the 'visible' bit
    // is taken from VisWinAnnotations::AddAnnotationObject
    int const static CREATE_ANNOTATION_OBJECT_AS_NOT_VISIBLE = 0x00010000;
    std::string visible("1");
    // Check that annotType is between 0 and 8 inclusive.
    // These numbers represent the annotationTypes that are available
    // for user to 'Add'. Legend is currently the only annotation type
    // not part of the user-addable set.
    // See AnnotationObject.h for the enums available for Annotation type.
    if (!(0 <= annotType && annotType <= 8))
    {
        if (annotType & CREATE_ANNOTATION_OBJECT_AS_NOT_VISIBLE)
            visible = "0";
        annotType &= ~CREATE_ANNOTATION_OBJECT_AS_NOT_VISIBLE;
    }

    std::string annotTypeName =
      AnnotationObject::AnnotationType_ToString(AnnotationObject::AnnotationType(annotType));
    std::string annotName =rpc->GetStringArg1();

    std::string annotTypeLower(annotTypeName);
    std::transform(annotTypeLower.begin(), annotTypeLower.end(), annotTypeLower.begin(), ::tolower);
    return visitmodule() + annotTypeLower + std::string(" = CreateAnnotationObject(\"") +
           annotTypeName + std::string("\", \"") +
           annotName     + std::string("\", \"") +
           visible       + std::string("\")\n\n");
}

static std::string log_HideActiveAnnotationObjectsRPC(ViewerRPC *rpc)
{
    AnnotationObjectList *aol =
        viewer->GetViewerState()->GetAnnotationObjectList();

    std::string all;
    for(size_t i = 0; i < size_t(aol->GetNumAnnotations()); ++i)
    {
        const AnnotationObject &annot = aol->GetAnnotation(i);
        if(annot.GetActive())
        {
            std::string typeName;
            if (annot.GetObjectType() == AnnotationObject::LegendAttributes)
            {
                // since legends are associated with a plot,  the object
                // name will be something like 'Plot0000'.  So, use the
                // object name, replacing 'Plot' with 'legend' to better
                // better associate it with the correct plot.
                typeName=annot.GetObjectName();
                typeName.replace(0,4, "legend");
            }
            else
            {
                typeName=(AnnotationObject::AnnotationType_ToString(annot.GetObjectType()));
                std::transform(typeName.begin(), typeName.end(), typeName.begin(), ::tolower);
            }
            std::string s = typeName +
                            " = GetAnnotationObject(\"" +
                            annot.GetObjectName() +
                            "\")\n";
            if(annot.GetVisible())
                s += typeName + ".visible = 0\n";
            else
                s += typeName + ".visible = 1\n";
            all += s + "\n";
        }
    }

    return all;
}

static std::string log_DeleteActiveAnnotationObjectsRPC(ViewerRPC *rpc)
{
    AnnotationObjectList *aol =
        viewer->GetViewerState()->GetAnnotationObjectList();

    std::string all;
    for(size_t i = 0; i < size_t(aol->GetNumAnnotations()); ++i)
    {
        const AnnotationObject &annot = aol->GetAnnotation(i);
        if(annot.GetActive())
        {
            std::string typeName;
            if (annot.GetObjectType() == AnnotationObject::LegendAttributes)
            {
                // since legends are associated with a plot,  the object
                // name will be something like 'Plot0000'.  So, use the
                // object name, replacing 'Plot' with 'legend' to better
                // better associate it with the correct plot.
                typeName=annot.GetObjectName();
                typeName.replace(0,4, "legend");
            }
            else
            {
                typeName=(AnnotationObject::AnnotationType_ToString(annot.GetObjectType()));
                std::transform(typeName.begin(), typeName.end(), typeName.begin(), ::tolower);
            }
            std::string s = typeName +
                           " = GetAnnotationObject(\"" +
                           annot.GetObjectName() +
                           "\")\n";
             s += typeName + ".Delete()\n";
            all += s + "\n";
        }
    }

    return all;
}

// this isn't relevant in the cli.
#if 0
static std::string log_RaiseActiveAnnotationObjectsRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("RaiseActiveAnnotationObjects", MSG_NOT_IMPLEMENTED);
}

static std::string log_LowerActiveAnnotationObjectsRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("LowerActiveAnnotationObjects", MSG_NOT_IMPLEMENTED);
}
#endif

static std::string log_SetAnnotationObjectOptionsRPC(ViewerRPC *rpc)
{
    AnnotationObjectList *aol =
        viewer->GetViewerState()->GetAnnotationObjectList();

    std::string all;
    for(size_t i = 0; i < size_t(aol->GetNumAnnotations()); ++i)
    {
        const AnnotationObject &annot = aol->GetAnnotation(i);
        if(annot.GetActive())
        {
            std::string s;
            std::string type(AnnotationObject::AnnotationType_ToString(annot.GetObjectType()));
            std::transform(type.begin(), type.end(), type.begin(), ::tolower);
            switch(annot.GetObjectType())
            {
                case AnnotationObject::Text2D:
                    s = PyText2DObject_ToString(&annot, (type + ".").c_str());
                    break;
                case AnnotationObject::Text3D:
                    s = PyText3DObject_ToString(&annot, (type + ".").c_str());
                     break;
                case AnnotationObject::TimeSlider:
                    s = PyTimeSliderObject_ToString(&annot, (type + ".").c_str());
                     break;
                case AnnotationObject::Line2D:
                    s = PyLineObject_ToString(&annot, (type + ".").c_str());
                     break;
                case AnnotationObject::Line3D:
                    s = PyLine3DObject_ToString(&annot, (type + ".") .c_str());
                     break;
                case AnnotationObject::Image:
                    s = PyImageObject_ToString(&annot, (type + ".") .c_str());
                     break;
                case AnnotationObject::LegendAttributes:
                    // since legends are associated with a plot,  the object
                    // name will be something like 'Plot0000'.  So, use the
                    // object name, replacing 'Plot' with 'legend' to better
                    // better associate it with the correct plot.
                    type=annot.GetObjectName();
                    type.replace(0,4, "legend");
                    s = PyLegendAttributesObject_ToString(&annot, (type + ".") .c_str());
                     break;
                default:
                     break;
            }
            if(!s.empty())
            {
                std::string getObj = type +
                            " = GetAnnotationObject(\"" +
                            annot.GetObjectName() +
                            "\")\n";
                all += visitmodule() + getObj + s + "\n";
           }
        }
    }
    return all;
}

static std::string log_SetDefaultAnnotationObjectListRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("SetDefaultAnnotationObjectList", MSG_NOT_IMPLEMENTED);
}

static std::string log_ResetAnnotationObjectListRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("ResetAnnotationObjectList", MSG_NOT_IMPLEMENTED);
}

static std::string log_ResetPickLetterRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ResetPickLetter()\n");
}

static std::string log_RenamePickLabelRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("RenamePickLabel(\"") +
           rpc->GetStringArg1() + std::string("\", \"") +
           rpc->GetStringArg2() + std::string("\")\n");
}

static std::string log_SetDefaultPickAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyPickAttributes_GetLogString()));
    s += "SetDefaultPickAttributes(PickAtts)\n";
    return visitmodule() + s;

}

static std::string log_ChooseCenterOfRotationRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    if(rpc->GetBoolFlag())
    {
        snprintf(str, SLEN, "ChooseCenterOfRotation(%g, %g)\n",
                 rpc->GetQueryPoint1()[0], rpc->GetQueryPoint1()[1]);
    }
    else
    {
        snprintf(str, SLEN, "ChooseCenterOfRotation()\n");
    }
    return visitmodule() + std::string(str);
}

static std::string log_SetCenterOfRotationRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetCenterOfRotation(%g, %g, %g)\n",
             rpc->GetQueryPoint1()[0], rpc->GetQueryPoint1()[1],
             rpc->GetQueryPoint1()[2]);
    return visitmodule() + std::string(str);
}

static std::string log_SetQueryOverTimeAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyQueryOverTimeAttributes_GetLogString()));
    s += "SetQueryOverTimeAttributes(QueryOverTimeAtts)\n";
    return visitmodule() + s;
}

static std::string log_SetDefaultQueryOverTimeAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyQueryOverTimeAttributes_GetLogString()));
    s += "SetDefaultQueryOverTimeAttributes(QueryOverTimeAtts)\n";
    return visitmodule() + s;
}

static std::string log_ResetQueryOverTimeAttributesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ResetQueryOverTimeAttributes()\n");
}

static std::string log_ResetLineoutColorRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ResetLineoutColor()\n");
}

static std::string log_SetInteractorAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyInteractorAttributes_GetLogString()));
    s += "SetInteractorAttributes(InteractorAtts)\n";
    return visitmodule() + s;
}

static std::string log_SetDefaultInteractorAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyInteractorAttributes_GetLogString()));
    s += "SetDefaultInteractorAttributes(InteractorAtts)\n";
    return visitmodule() + s;
}

static std::string log_ResetInteractorAttributesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ResetInteractorAttributes()\n");
}

static std::string log_GetProcInfoRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("GetProcInfo", MSG_UNSUPPORTED);
}

static std::string log_SendSimulationCommandRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    if (rpc->GetStringArg2().length() > 0)
        snprintf(str, SLEN,
                "SendSimulationCommand(\"%s\", \"%s\", \"%s\", \"%s\")\n",
                 rpc->GetProgramHost().c_str(), rpc->GetProgramSim().c_str(),
                 rpc->GetStringArg1().c_str(), rpc->GetStringArg2().c_str());
    else
        snprintf(str, SLEN, "SendSimulationCommand(\"%s\", \"%s\", \"%s\")\n",
                 rpc->GetProgramHost().c_str(), rpc->GetProgramSim().c_str(),
                 rpc->GetStringArg1().c_str());
    return visitmodule() + std::string(str);
}

static std::string log_UpdateDBPluginInfoRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("UpdateDBPluginInfo", MSG_UNSUPPORTED);
}

static std::string log_ConstructDataBinningRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyConstructDataBinningAttributes_GetLogString()));
    s += "ConstructDataBinning(ConstructDataBinningAtts)\n";
    return visitmodule() + s;
}

static std::string log_ExportDBRPC(ViewerRPC *rpc)
{
#if 0
// This commented out due to crash in
// PyDBOptionsAttributes_CreateDictionaryFromDBOptions
// (Ticket #17008)

    std::string s(constructor(PyExportDBAttributes_GetLogString()));

    // if ops were included, we need to call differently
    if(s.find("DBExportOpts =") !=std::string::npos )
    {
        s += "ExportDatabase(ExportDBAtts, DBExportOpts)\n";
    }
    else // export w/o opts
    {
        s += "ExportDatabase(ExportDBAtts)\n";
    }
#else
    std::string s("Logging of ExportDatabase currently disabled.\n");
#endif
    return visitmodule() + s;
}

static std::string log_SetTryHarderCyclesTimesRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetTryHarderCyclesTimes(%d)\n", rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_SuppressQueryOutputRPC(ViewerRPC *rpc)
{
    std::string s;
    if(rpc->GetBoolFlag())
        s = std::string("SuppressQueryOutputOn()\n");
    else
        s = std::string("SuppressQueryOutputOff()\n");
    return visitmodule() + s;
}

static std::string log_SetMeshManagementAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyMeshManagementAttributes_GetLogString()));
    s += "SetMeshManagementAttributes(MeshManagementAtts)\n";
    return visitmodule() + s;
}

static std::string log_SetDefaultMeshManagementAttributesRPC(ViewerRPC *rpc)
{
    std::string s(constructor(PyMeshManagementAttributes_GetLogString()));
    s += "SetDefaultMeshManagementAttributes(MeshManagementAtts)\n";
    return visitmodule() + s;
}

static std::string log_ResetMeshManagementAttributesRPC(ViewerRPC *rpc)
{
    return MESSAGE_COMMENT("ResetMeshManagementAttributes", MSG_UNSUPPORTED);
}

static std::string log_ResizeWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "ResizeWindow(%d, %d, %d)\n", rpc->GetWindowId(),
             rpc->GetIntArg1(), rpc->GetIntArg2());
    return visitmodule() + std::string(str);
}

static std::string log_MoveWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MoveWindow(%d, %d, %d)\n", rpc->GetWindowId(),
             rpc->GetIntArg1(), rpc->GetIntArg2());
    return visitmodule() + std::string(str);
}

static std::string log_MoveAndResizeWindowRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "ResizeWindow(%d, %d, %d, %d, %d)\n", rpc->GetWindowId(),
             rpc->GetIntArg1(), rpc->GetIntArg2(), rpc->GetIntArg3(),
             rpc->GetWindowLayout());
    return visitmodule() + std::string(str);
}

static std::string log_RequestMetaDataRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "metadata = %sGetMetaData(\"%s\", %d)\n",
             visitmodule().c_str(), EscapeFilename(rpc->GetDatabase()).c_str(), rpc->GetStateNumber());
    return std::string(str);
}

static std::string log_SetQueryFloatFormatRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetQueryFloatFormat(\"%s\")\n",
                        rpc->GetStringArg1().c_str());
    return visitmodule() + std::string(str);
}

static std::string log_SetPlotFollowsTimeRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("SetPlotFollowsTime()\n");
}

static std::string log_CreateNamedSelectionRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("CreateNamedSelection(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_DeleteNamedSelectionRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("DeleteNamedSelection(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_LoadNamedSelectionRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("LoadNamedSelection(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_SaveNamedSelectionRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("SaveNamedSelection(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_ApplyNamedSelectionRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("ApplyNamedSelection(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_SetNamedSelectionAutoApplyRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("SetNamedSelectionAutoApply(\"") + std::string(rpc->GetBoolFlag()?"1":"0") + "\")\n";
}

static std::string log_UpdateNamedSelectionRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("UpdateNamedSelection(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_InitializeNamedSelectionVariablesRPC(ViewerRPC *rpc)
{
    return visitmodule() + std::string("InitializeNamedSelectionVariables(\"") + rpc->GetStringArg1() + "\")\n";
}

static std::string log_SetPlotDescriptionRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetPlotDescription(%d, \"%s\")\n", rpc->GetIntArg1(), rpc->GetStringArg1().c_str());
    return visitmodule() + std::string(str);
}

static std::string log_MovePlotOrderTowardLastRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MovePlotOrderTowardLast(%d)\n", rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_MovePlotOrderTowardFirstRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "MovePlotOrderTowardFirst(%d)\n", rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_SetPlotOrderToLastRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetPlotOrderToLast(%d)\n", rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

static std::string log_SetPlotOrderToFirstRPC(ViewerRPC *rpc)
{
    char str[SLEN];
    snprintf(str, SLEN, "SetPlotOrderToFirst(%d)\n", rpc->GetIntArg1());
    return visitmodule() + std::string(str);
}

// ****************************************************************************
// Method: LogRPCs
//
// Purpose:
//   This is a callback function used for logging that dispatches to other
//   RPC-specific logging functions.
//
// Arguments:
//   subj : The RPC that caused the function to get called.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jan 10 10:05:19 PDT 2006
//
// Modifications:
//   Hank Childs, Mon Feb 13 21:39:02 PST 2006
//   Added ConstructDDFRPC.
//
//   Brad Whitlock, Fri Mar 9 17:48:59 PST 2007
//   Added RequestMetaDataRPC.
//
//   Brad Whitlock, Tue May 8 16:32:06 PST 2007
//   Added debug5 logging.
//
//   Cyrus Harrison, Tue Jan  8 08:01:51 PST 2008
//   Added SetQueryFloatFormatRPC.
//
//   Brad Whitlock, Tue Oct 20 16:19:15 PDT 2009
//   I added the new RPCs that control the plot list ordering.
//
//   Brad Whitlock, Mon Nov  9 14:59:03 PST 2009
//   I made it use strings more instead of a fixed sized buffer so we would
//   be less likely to cut off longer strings such as plot attributes.
//
//   Jeremy Meredith, Wed Feb  3 15:35:08 EST 2010
//   Removed maintain data; moved maintain view from Global settings
//   (Main window) to per-window Window Information (View window).
//
//   Brad Whitlock, Fri Aug 13 14:57:23 PDT 2010
//   I added UpdateNamedSelection.
//
//   Hank Childs, Sat Aug 21 14:05:14 PDT 2010
//   Rename ddf to data binning.
//
//   Brad Whitlock, Fri Aug 27 10:43:32 PDT 2010
//   I added RenamePickLabel.
//
//   Brad Whitlock, Tue May 31 17:14:27 PDT 2011
//   Do not return early when the log file is not open because that breaks
//   command recording.
//
//   Kathleen Biagas, Wed Jan  9 11:32:39 PST 2013
//   Added GetQueryParameters.
//
//   Eric Brugger, Wed Mar 22 16:23:12 PDT 2023
//   Added operator keyframing.
//
// ****************************************************************************

void
LogRPCs(Subject *subj, void *)
{
    std::string str;
    bool record = true;

    // empty the string.
    str[0] = '\0';

    ViewerRPC *rpc = (ViewerRPC *)subj;
    debug5 << "Logging: " << ViewerRPC::ViewerRPCType_ToString(rpc->GetRPCType()).c_str() << endl;

    switch(rpc->GetRPCType())
    {
    case ViewerRPC::SetStateLoggingRPC:
        LogFile_SetEnabled(rpc->GetBoolFlag());
        record = false;
        break;

    // The rpc's that we want to log.
    case ViewerRPC::AddWindowRPC:
        str = log_AddWindowRPC(rpc);
        break;
    case ViewerRPC::DeleteWindowRPC:
        str = log_DeleteWindowRPC(rpc);
        break;
    case ViewerRPC::SetWindowLayoutRPC:
        str = log_SetWindowLayoutRPC(rpc);
        break;
    case ViewerRPC::SetActiveWindowRPC:
        str = log_SetActiveWindowRPC(rpc);
        break;
    case ViewerRPC::ClearWindowRPC:
        str = log_ClearWindowRPC(rpc);
        break;
    case ViewerRPC::ClearAllWindowsRPC:
        str = log_ClearAllWindowsRPC(rpc);
        break;
    case ViewerRPC::OpenDatabaseRPC:
        str = log_OpenDatabaseRPC(rpc);
        break;
    case ViewerRPC::CloseDatabaseRPC:
        str = log_CloseDatabaseRPC(rpc);
        break;
    case ViewerRPC::ActivateDatabaseRPC:
        str = log_ActivateDatabaseRPC(rpc);
        break;
    case ViewerRPC::CheckForNewStatesRPC:
        str = log_CheckForNewStatesRPC(rpc);
        break;
    case ViewerRPC::CreateDatabaseCorrelationRPC:
        str = log_CreateDatabaseCorrelationRPC(rpc);
        break;
    case ViewerRPC::AlterDatabaseCorrelationRPC:
        str = log_AlterDatabaseCorrelationRPC(rpc);
        break;
    case ViewerRPC::DeleteDatabaseCorrelationRPC:
        str = log_DeleteDatabaseCorrelationRPC(rpc);
        break;
    case ViewerRPC::ReOpenDatabaseRPC:
        str = log_ReOpenDatabaseRPC(rpc);
        break;
    case ViewerRPC::ReplaceDatabaseRPC:
        str = log_ReplaceDatabaseRPC(rpc);
        break;
    case ViewerRPC::OverlayDatabaseRPC:
        str = log_OverlayDatabaseRPC(rpc);
        break;
    case ViewerRPC::OpenComputeEngineRPC:
        str = log_OpenComputeEngineRPC(rpc);
        break;
    case ViewerRPC::CloseComputeEngineRPC:
        str = log_CloseComputeEngineRPC(rpc);
        break;
    case ViewerRPC::AnimationSetNFramesRPC:
        str = log_AnimationSetNFramesRPC(rpc);
        break;
    case ViewerRPC::AnimationPlayRPC:
        str = log_AnimationPlayRPC(rpc);
        break;
    case ViewerRPC::AnimationReversePlayRPC:
        str = log_AnimationReversePlayRPC(rpc);
        break;
    case ViewerRPC::AnimationStopRPC:
        str = log_AnimationStopRPC(rpc);
        break;
    case ViewerRPC::TimeSliderNextStateRPC:
        str = log_TimeSliderNextStateRPC(rpc);
        break;
    case ViewerRPC::TimeSliderPreviousStateRPC:
        str = log_TimeSliderPreviousStateRPC(rpc);
        break;
    case ViewerRPC::SetTimeSliderStateRPC:
        str = log_SetTimeSliderStateRPC(rpc);
        break;
    case ViewerRPC::SetActiveTimeSliderRPC:
        str = log_SetActiveTimeSliderRPC(rpc);
        break;
    case ViewerRPC::AddPlotRPC:
        str = log_AddPlotRPC(rpc);
        break;
    case ViewerRPC::SetPlotFrameRangeRPC:
        str = log_SetPlotFrameRangeRPC(rpc);
        break;
    case ViewerRPC::DeletePlotKeyframeRPC:
        str = log_DeletePlotKeyframeRPC(rpc);
        break;
    case ViewerRPC::MovePlotKeyframeRPC:
        str = log_MovePlotKeyframeRPC(rpc);
        break;
    case ViewerRPC::DeleteActivePlotsRPC:
        str = log_DeleteActivePlotsRPC(rpc);
        break;
    case ViewerRPC::HideActivePlotsRPC:
        str = log_HideActivePlotsRPC(rpc);
        break;
    case ViewerRPC::DrawPlotsRPC:
        str = log_DrawPlotsRPC(rpc);
        break;
    case ViewerRPC::DisableRedrawRPC:
        str = log_DisableRedrawRPC(rpc);
        break;
    case ViewerRPC::RedrawRPC:
        str = log_RedrawRPC(rpc);
        break;
    case ViewerRPC::SetActivePlotsRPC:
        str = log_SetActivePlotsRPC(rpc);
        break;
    case ViewerRPC::ChangeActivePlotsVarRPC:
        str = log_ChangeActivePlotsVarRPC(rpc);
        break;
    case ViewerRPC::AddOperatorRPC:
        str = log_AddOperatorRPC(rpc);
        break;
    case ViewerRPC::AddInitializedOperatorRPC:
        str = log_AddInitializedOperatorRPC(rpc);
        break;
    case ViewerRPC::DeleteOperatorKeyframeRPC:
        str = log_DeleteOperatorKeyframeRPC(rpc);
        break;
    case ViewerRPC::MoveOperatorKeyframeRPC:
        str = log_MoveOperatorKeyframeRPC(rpc);
        break;
    case ViewerRPC::PromoteOperatorRPC:
        str = log_PromoteOperatorRPC(rpc);
        break;
    case ViewerRPC::DemoteOperatorRPC:
        str = log_DemoteOperatorRPC(rpc);
        break;
    case ViewerRPC::RemoveOperatorRPC:
        str = log_RemoveOperatorRPC(rpc);
        break;
    case ViewerRPC::RemoveLastOperatorRPC:
        str = log_RemoveLastOperatorRPC(rpc);
        break;
    case ViewerRPC::RemoveAllOperatorsRPC:
        str = log_RemoveAllOperatorsRPC(rpc);
        break;
    case ViewerRPC::SaveWindowRPC:
        str = log_SaveWindowRPC(rpc);
        break;
    case ViewerRPC::SetDefaultPlotOptionsRPC:
        str = log_SetDefaultPlotOptionsRPC(rpc);
        break;
    case ViewerRPC::SetPlotOptionsRPC:
        str = log_SetPlotOptionsRPC(rpc);
        break;
    case ViewerRPC::SetDefaultOperatorOptionsRPC:
        str = log_SetDefaultOperatorOptionsRPC(rpc);
        break;
    case ViewerRPC::SetOperatorOptionsRPC:
        str = log_SetOperatorOptionsRPC(rpc);
        break;
    case ViewerRPC::WriteConfigFileRPC:
        str = log_WriteConfigFileRPC(rpc);
        break;
    case ViewerRPC::IconifyAllWindowsRPC:
        str = log_IconifyAllWindowsRPC(rpc);
        break;
    case ViewerRPC::DeIconifyAllWindowsRPC:
        str = log_DeIconifyAllWindowsRPC(rpc);
        break;
    case ViewerRPC::ShowAllWindowsRPC:
        str = log_ShowAllWindowsRPC(rpc);
        break;
    case ViewerRPC::HideAllWindowsRPC:
        str = log_HideAllWindowsRPC(rpc);
        break;
    case ViewerRPC::SetAnnotationAttributesRPC:
        str = log_SetAnnotationAttributesRPC(rpc);
        break;
    case ViewerRPC::SetDefaultAnnotationAttributesRPC:
        str = log_SetDefaultAnnotationAttributesRPC(rpc);
        break;
    case ViewerRPC::ResetAnnotationAttributesRPC:
        str = log_ResetAnnotationAttributesRPC(rpc);
        break;
    case ViewerRPC::SetKeyframeAttributesRPC:
        str = log_SetKeyframeAttributesRPC(rpc);
        break;
    case ViewerRPC::SetPlotSILRestrictionRPC:
        str = log_SetPlotSILRestrictionRPC(rpc);
        break;
    case ViewerRPC::SetViewAxisArrayRPC:
        str = log_SetViewAxisArrayRPC(rpc);
        break;
    case ViewerRPC::SetViewCurveRPC:
        str = log_SetViewCurveRPC(rpc);
        break;
    case ViewerRPC::SetView2DRPC:
        str = log_SetView2DRPC(rpc);
        break;
    case ViewerRPC::SetView3DRPC:
        str = log_SetView3DRPC(rpc);
        break;
    case ViewerRPC::ResetPlotOptionsRPC:
        str = log_ResetPlotOptionsRPC(rpc);
        break;
    case ViewerRPC::ResetOperatorOptionsRPC:
        str = log_ResetOperatorOptionsRPC(rpc);
        break;
    case ViewerRPC::SetAppearanceRPC:
        str = log_SetAppearanceRPC(rpc);
        break;
    case ViewerRPC::ProcessExpressionsRPC:
        str = log_ProcessExpressionsRPC(rpc);
        break;
    case ViewerRPC::SetLightListRPC:
        str = log_SetLightListRPC(rpc);
        break;
    case ViewerRPC::SetDefaultLightListRPC:
        str = log_SetDefaultLightListRPC(rpc);
        break;
    case ViewerRPC::ResetLightListRPC:
        str = log_ResetLightListRPC(rpc);
        break;
    case ViewerRPC::SetAnimationAttributesRPC:
        str = log_SetAnimationAttributesRPC(rpc);
        break;
    case ViewerRPC::SetWindowAreaRPC:
        str = log_SetWindowAreaRPC(rpc);
        break;
    case ViewerRPC::PrintWindowRPC:
        str = log_PrintWindowRPC(rpc);
        break;
    case ViewerRPC::ResetViewRPC:
        str = log_ResetViewRPC(rpc);
        break;
    case ViewerRPC::RecenterViewRPC:
        str = log_RecenterViewRPC(rpc);
        break;
    case ViewerRPC::ToggleMaintainViewModeRPC:
        str = log_ToggleMaintainViewModeRPC(rpc);
        break;
    case ViewerRPC::ToggleBoundingBoxModeRPC:
        str = log_ToggleBoundingBoxModeRPC(rpc);
        break;
    case ViewerRPC::ToggleCameraViewModeRPC:
        str = log_ToggleCameraViewModeRPC(rpc);
        break;
    case ViewerRPC::TogglePerspectiveViewRPC:
        str = log_TogglePerspectiveViewRPC(rpc);
        break;
    case ViewerRPC::ToggleSpinModeRPC:
        str = log_ToggleSpinModeRPC(rpc);
        break;
    case ViewerRPC::ToggleLockTimeRPC:
        str = log_ToggleLockTimeRPC(rpc);
        break;
    case ViewerRPC::ToggleLockToolsRPC:
        str = log_ToggleLockToolsRPC(rpc);
        break;
    case ViewerRPC::ToggleLockViewModeRPC:
        str = log_ToggleLockViewModeRPC(rpc);
        break;
    case ViewerRPC::ToggleFullFrameRPC:
        str = log_ToggleFullFrameRPC(rpc);
        break;
    case ViewerRPC::UndoViewRPC:
        str = log_UndoViewRPC(rpc);
        break;
    case ViewerRPC::RedoViewRPC:
        str = log_RedoViewRPC(rpc);
        break;
    case ViewerRPC::InvertBackgroundRPC:
        str = log_InvertBackgroundRPC(rpc);
        break;
    case ViewerRPC::ClearPickPointsRPC:
        str = log_ClearPickPointsRPC(rpc);
        break;
    case ViewerRPC::RemovePicksRPC:
        str = log_RemovePicksRPC(rpc);
        break;
    case ViewerRPC::SetWindowModeRPC:
        str = log_SetWindowModeRPC(rpc);
        break;
    case ViewerRPC::EnableToolRPC:
        str = log_EnableToolRPC(rpc);
        break;
    case ViewerRPC::CopyViewToWindowRPC:
        str = log_CopyViewToWindowRPC(rpc);
        break;
    case ViewerRPC::CopyLightingToWindowRPC:
        str = log_CopyLightingToWindowRPC(rpc);
        break;
    case ViewerRPC::CopyAnnotationsToWindowRPC:
        str = log_CopyAnnotationsToWindowRPC(rpc);
        break;
    case ViewerRPC::CopyPlotsToWindowRPC:
        str = log_CopyPlotsToWindowRPC(rpc);
        break;
    case ViewerRPC::ClearCacheRPC:
        str = log_ClearCacheRPC(rpc);
        break;
    case ViewerRPC::ClearCacheForAllEnginesRPC:
        str = log_ClearCacheForAllEnginesRPC(rpc);
        break;
    case ViewerRPC::SetViewExtentsTypeRPC:
        str = log_SetViewExtentsTypeRPC(rpc);
        break;
    case ViewerRPC::ClearRefLinesRPC:
        str = log_ClearRefLinesRPC(rpc);
        break;
    case ViewerRPC::SetRenderingAttributesRPC:
        str = log_SetRenderingAttributesRPC(rpc);
        break;
    case ViewerRPC::QueryRPC:
        str = log_QueryRPC(rpc);
        break;
    case ViewerRPC::CloneWindowRPC:
        str = log_CloneWindowRPC(rpc);
        break;
    case ViewerRPC::SetMaterialAttributesRPC:
        str = log_SetMaterialAttributesRPC(rpc);
        break;
    case ViewerRPC::SetDefaultMaterialAttributesRPC:
        str = log_SetDefaultMaterialAttributesRPC(rpc);
        break;
    case ViewerRPC::ResetMaterialAttributesRPC:
        str = log_ResetMaterialAttributesRPC(rpc);
        break;
    case ViewerRPC::SetPlotDatabaseStateRPC:
        str = log_SetPlotDatabaseStateRPC(rpc);
        break;
    case ViewerRPC::DeletePlotDatabaseKeyframeRPC:
        str = log_DeletePlotDatabaseKeyframeRPC(rpc);
        break;
    case ViewerRPC::MovePlotDatabaseKeyframeRPC:
        str = log_MovePlotDatabaseKeyframeRPC(rpc);
        break;
    case ViewerRPC::ClearViewKeyframesRPC:
        str = log_ClearViewKeyframesRPC(rpc);
        break;
    case ViewerRPC::DeleteViewKeyframeRPC:
        str = log_DeleteViewKeyframeRPC(rpc);
        break;
    case ViewerRPC::MoveViewKeyframeRPC:
        str = log_MoveViewKeyframeRPC(rpc);
        break;
    case ViewerRPC::SetViewKeyframeRPC:
        str = log_SetViewKeyframeRPC(rpc);
        break;
    case ViewerRPC::OpenMDServerRPC:
        str = log_OpenMDServerRPC(rpc);
        break;
    case ViewerRPC::EnableToolbarRPC:
        str = log_EnableToolbarRPC(rpc);
        break;
    case ViewerRPC::HideToolbarsRPC:
        str = log_HideToolbarsRPC(rpc);
        break;
    case ViewerRPC::HideToolbarsForAllWindowsRPC:
        str = log_HideToolbarsForAllWindowsRPC(rpc);
        break;
    case ViewerRPC::ShowToolbarsRPC:
        str = log_ShowToolbarsRPC(rpc);
        break;
    case ViewerRPC::ShowToolbarsForAllWindowsRPC:
        str = log_ShowToolbarsForAllWindowsRPC(rpc);
        break;
    case ViewerRPC::SetToolbarIconSizeRPC:
        str = log_SetToolbarIconSizeRPC(rpc);
        break;
    case ViewerRPC::SaveViewRPC:
        str = log_SaveViewRPC(rpc);
        break;
    case ViewerRPC::SetGlobalLineoutAttributesRPC:
        str = log_SetGlobalLineoutAttributesRPC(rpc);
        break;
    case ViewerRPC::SetPickAttributesRPC:
        str = log_SetPickAttributesRPC(rpc);
        break;
    case ViewerRPC::ExportColorTableRPC:
        str = log_ExportColorTableRPC(rpc);
        break;
    case ViewerRPC::ExportEntireStateRPC:
        str = log_ExportEntireStateRPC(rpc);
        break;
    case ViewerRPC::ImportEntireStateRPC:
        str = log_ImportEntireStateRPC(rpc);
        break;
    case ViewerRPC::ImportEntireStateWithDifferentSourcesRPC:
        str = log_ImportEntireStateWithDifferentSourcesRPC(rpc);
        break;
    case ViewerRPC::ResetPickAttributesRPC:
        str = log_ResetPickAttributesRPC(rpc);
        break;
    case ViewerRPC::AddAnnotationObjectRPC:
        str = log_AddAnnotationObjectRPC(rpc);
        break;
    case ViewerRPC::HideActiveAnnotationObjectsRPC:
        str = log_HideActiveAnnotationObjectsRPC(rpc);
        break;
    case ViewerRPC::DeleteActiveAnnotationObjectsRPC:
        str = log_DeleteActiveAnnotationObjectsRPC(rpc);
        break;
#if 0
    case ViewerRPC::RaiseActiveAnnotationObjectsRPC:
        str = log_RaiseActiveAnnotationObjectsRPC(rpc);
        break;
    case ViewerRPC::LowerActiveAnnotationObjectsRPC:
        str = log_LowerActiveAnnotationObjectsRPC(rpc);
        break;
#endif
    case ViewerRPC::SetAnnotationObjectOptionsRPC:
        str = log_SetAnnotationObjectOptionsRPC(rpc);
        break;
    case ViewerRPC::SetDefaultAnnotationObjectListRPC:
        str = log_SetDefaultAnnotationObjectListRPC(rpc);
        break;
    case ViewerRPC::ResetAnnotationObjectListRPC:
        str = log_ResetAnnotationObjectListRPC(rpc);
        break;
    case ViewerRPC::ResetPickLetterRPC:
        str = log_ResetPickLetterRPC(rpc);
        break;
    case ViewerRPC::SetDefaultPickAttributesRPC:
        str = log_SetDefaultPickAttributesRPC(rpc);
        break;
    case ViewerRPC::ChooseCenterOfRotationRPC:
        str = log_ChooseCenterOfRotationRPC(rpc);
        break;
    case ViewerRPC::SetCenterOfRotationRPC:
        str = log_SetCenterOfRotationRPC(rpc);
        break;
    case ViewerRPC::SetQueryOverTimeAttributesRPC:
        str = log_SetQueryOverTimeAttributesRPC(rpc);
        break;
    case ViewerRPC::SetDefaultQueryOverTimeAttributesRPC:
        str = log_SetDefaultQueryOverTimeAttributesRPC(rpc);
        break;
    case ViewerRPC::ResetQueryOverTimeAttributesRPC:
        str = log_ResetQueryOverTimeAttributesRPC(rpc);
        break;
    case ViewerRPC::ResetLineoutColorRPC:
        str = log_ResetLineoutColorRPC(rpc);
        break;
    case ViewerRPC::SetInteractorAttributesRPC:
        str = log_SetInteractorAttributesRPC(rpc);
        break;
    case ViewerRPC::SetDefaultInteractorAttributesRPC:
        str = log_SetDefaultInteractorAttributesRPC(rpc);
        break;
    case ViewerRPC::ResetInteractorAttributesRPC:
        str = log_ResetInteractorAttributesRPC(rpc);
        break;
    case ViewerRPC::GetProcInfoRPC:
        str = log_GetProcInfoRPC(rpc);
        break;
    case ViewerRPC::SendSimulationCommandRPC:
        str = log_SendSimulationCommandRPC(rpc);
        break;
    case ViewerRPC::UpdateDBPluginInfoRPC:
        str = log_UpdateDBPluginInfoRPC(rpc);
        break;
    case ViewerRPC::ExportDBRPC:
        str = log_ExportDBRPC(rpc);
        break;
    case ViewerRPC::SetTryHarderCyclesTimesRPC:
        str = log_SetTryHarderCyclesTimesRPC(rpc);
        break;
    case ViewerRPC::SuppressQueryOutputRPC:
        str = log_SuppressQueryOutputRPC(rpc);
        break;
    case ViewerRPC::SetMeshManagementAttributesRPC:
        str = log_SetMeshManagementAttributesRPC(rpc);
        break;
    case ViewerRPC::SetDefaultMeshManagementAttributesRPC:
        str = log_SetDefaultMeshManagementAttributesRPC(rpc);
        break;
    case ViewerRPC::ResetMeshManagementAttributesRPC:
        str = log_ResetMeshManagementAttributesRPC(rpc);
        break;
    case ViewerRPC::ResizeWindowRPC:
        str = log_ResizeWindowRPC(rpc);
        break;
    case ViewerRPC::MoveWindowRPC:
        str = log_MoveWindowRPC(rpc);
        break;
    case ViewerRPC::MoveAndResizeWindowRPC:
        str = log_MoveAndResizeWindowRPC(rpc);
        break;
    case ViewerRPC::ConstructDataBinningRPC:
        str = log_ConstructDataBinningRPC(rpc);
        break;
    case ViewerRPC::RequestMetaDataRPC:
        str = log_RequestMetaDataRPC(rpc);
        break;
    case ViewerRPC::SetQueryFloatFormatRPC:
        str = log_SetQueryFloatFormatRPC(rpc);
        break;
    case ViewerRPC::SetPlotFollowsTimeRPC:
        str = log_SetPlotFollowsTimeRPC(rpc);
        break;
    case ViewerRPC::CreateNamedSelectionRPC:
        str = log_CreateNamedSelectionRPC(rpc);
        break;
    case ViewerRPC::DeleteNamedSelectionRPC:
        str = log_DeleteNamedSelectionRPC(rpc);
        break;
    case ViewerRPC::LoadNamedSelectionRPC:
        str = log_LoadNamedSelectionRPC(rpc);
        break;
    case ViewerRPC::SaveNamedSelectionRPC:
        str = log_SaveNamedSelectionRPC(rpc);
        break;
    case ViewerRPC::ApplyNamedSelectionRPC:
        str = log_ApplyNamedSelectionRPC(rpc);
        break;
    case ViewerRPC::SetNamedSelectionAutoApplyRPC:
        str = log_SetNamedSelectionAutoApplyRPC(rpc);
        break;
    case ViewerRPC::UpdateNamedSelectionRPC:
        str = log_UpdateNamedSelectionRPC(rpc);
        break;
    case ViewerRPC::InitializeNamedSelectionVariablesRPC:
        str = log_InitializeNamedSelectionVariablesRPC(rpc);
        break;
    case ViewerRPC::SetPlotDescriptionRPC:
        str = log_SetPlotDescriptionRPC(rpc);
        break;
    case ViewerRPC::MovePlotOrderTowardFirstRPC:
        str = log_MovePlotOrderTowardFirstRPC(rpc);
        break;
    case ViewerRPC::MovePlotOrderTowardLastRPC:
        str = log_MovePlotOrderTowardLastRPC(rpc);
        break;
    case ViewerRPC::SetPlotOrderToFirstRPC:
        str = log_SetPlotOrderToFirstRPC(rpc);
        break;
    case ViewerRPC::SetPlotOrderToLastRPC:
        str = log_SetPlotOrderToLastRPC(rpc);
        break;
    case ViewerRPC::RenamePickLabelRPC:
        str = log_RenamePickLabelRPC(rpc);
        break;
    case ViewerRPC::GetQueryParametersRPC:
        str = log_GetQueryParametersRPC(rpc);
        break;

    // RPCs that we don't want to log:
    case ViewerRPC::CloseRPC:
    case ViewerRPC::DetachRPC:
    case ViewerRPC::OpenClientRPC:
    case ViewerRPC::ConnectToMetaDataServerRPC:
    case ViewerRPC::UpdateColorTableRPC:

        // ... more ...
        record = false;
        break;

    // RPCs that we want to log but do not require anything special.
    default:
        {
        // Do the default behavior of stripping "RPC" from the name and
        // making a function call from the rpc name.
        std::string rpcName(ViewerRPC::ViewerRPCType_ToString(rpc->GetRPCType()));
        str = (std::string("# MAINTENANCE ISSUE: ") + rpcName) + " is not handled in "
                "Logging.C. Please contact a VisIt developer.\n";
        debug5 << str;
        }
        break;
    }

    if(record && logLevel == 0)
    {
        // Add the string to the macro string
        if(macroRecord)
            macroString += str;

        // Write to the log
        if(logFile != 0)
            fprintf(logFile, "%s", str.c_str());
    }
}

static const char *beginSpontaneousComment = "# Begin spontaneous state\n";
static const char *endSpontaneousComment = "# End spontaneous state\n\n";

#if 0
//
// Use this function someday to log spontaneous state changes for objects
// that we need to watch.
//
void
SpontaneousStateLogger(const std::string &s)
{
    if(LogFile_GetEnabled() && logLevel == 0)
    {
        // Objects that might need to be watched for spontaneous state:
        //
        // DatabaseCorrelationList
        //

        if(logFile != 0)
        {
            fprintf(logFile, "%s", beginSpontaneousComment);
            fprintf(logFile, "%s", s.c_str());
            fprintf(logFile, "%s", endSpontaneousComment);
        }

        if(macroRecord)
        {
            macroString += beginSpontaneousComment;
            macroString += s;
            macroString += endSpontaneousComment;
        }
    }
}
#endif

// ****************************************************************************
// Method: SS_log_ViewAxisArray
//
// Purpose:
//   This is a callback function for when ViewAxisArray state from the viewer
//   makes its way to the CLI as a result of a direct user interaction.
//
// Note:  view dimension of 4 is indicative of axis array view!
//
// Programmer: Jeremy Meredith
// Creation:   February  4, 2008
//
// Modifications:
//
// ****************************************************************************

void
SS_log_ViewAxisArray(const std::string &s)
{
    if(LogFile_GetEnabled() && logLevel == 0 &&
       viewer->GetViewerState()->GetWindowInformation()->GetViewDimension() == 4)
    {
        const char *v = "SetViewAxisArray(ViewAxisArrayAtts)\n";

        if(logFile != 0)
        {
            fprintf(logFile, "%s", beginSpontaneousComment);
            fprintf(logFile, "%s", s.c_str());
            fprintf(logFile, "%s%s", visitmodule().c_str(), v);
            fprintf(logFile, "%s", endSpontaneousComment);
        }

        if(macroRecord)
        {
            macroString += beginSpontaneousComment;
            macroString += s;
            macroString += visitmodule() + v;
            macroString += endSpontaneousComment;
        }
    }
}

// ****************************************************************************
// Method: SS_log_ViewCurve
//
// Purpose:
//   This is a callback function for when ViewCurve state from the viewer makes
//   its way to the CLI as a result of a direct user interaction.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jan 10 11:45:16 PDT 2006
//
// Modifications:
//
// ****************************************************************************

void
SS_log_ViewCurve(const std::string &s)
{
    if(LogFile_GetEnabled() && logLevel == 0 &&
       viewer->GetViewerState()->GetWindowInformation()->GetViewDimension() == 1)
    {
        const char *v = "SetViewCurve(ViewCurveAtts)\n";

        if(logFile != 0)
        {
            fprintf(logFile, "%s", beginSpontaneousComment);
            fprintf(logFile, "%s", constructor(s).c_str());
            fprintf(logFile, "%s%s", visitmodule().c_str(), v);
            fprintf(logFile, "%s", endSpontaneousComment);
        }

        if(macroRecord)
        {
            macroString += beginSpontaneousComment;
            macroString += constructor(s);
            macroString += visitmodule() + v;
            macroString += endSpontaneousComment;
        }
    }
}

// ****************************************************************************
// Method: SS_log_View2D
//
// Purpose:
//   This is a callback function for when View2D state from the viewer makes its
//   way to the CLI as a result of a direct user interaction.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jan 10 11:45:16 PDT 2006
//
// Modifications:
//
// ****************************************************************************

void
SS_log_View2D(const std::string &s)
{
    if(LogFile_GetEnabled() && logLevel == 0 &&
       viewer->GetViewerState()->GetWindowInformation()->GetViewDimension() == 2)
    {
        const char *v = "SetView2D(View2DAtts)\n";

        if(logFile != 0)
        {
            fprintf(logFile, "%s", beginSpontaneousComment);
            fprintf(logFile, "%s", constructor(s).c_str());
            fprintf(logFile, "%s%s", visitmodule().c_str(), v);
            fprintf(logFile, "%s", endSpontaneousComment);
        }

        if(macroRecord)
        {
            macroString += beginSpontaneousComment;
            macroString += constructor(s);
            macroString += visitmodule() + v;
            macroString += endSpontaneousComment;
        }
    }
}

// ****************************************************************************
// Method: SS_log_View3D
//
// Purpose:
//   This is a callback function for when View3D state from the viewer makes its
//   way to the CLI as a result of a direct user interaction.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jan 10 11:45:16 PDT 2006
//
// Modifications:
//
// ****************************************************************************

void
SS_log_View3D(const std::string &s)
{
    if(LogFile_GetEnabled() && logLevel == 0 &&
       viewer->GetViewerState()->GetWindowInformation()->GetViewDimension() == 3)
    {
        const char *v = "SetView3D(View3DAtts)\n";

        if(logFile != 0)
        {
            fprintf(logFile, "%s", beginSpontaneousComment);
            fprintf(logFile, "%s", constructor(s).c_str());
            fprintf(logFile, "%s%s", visitmodule().c_str(), v);
            fprintf(logFile, "%s", endSpontaneousComment);
        }

        if(macroRecord)
        {
            macroString += beginSpontaneousComment;
            macroString += constructor(s);
            macroString += visitmodule() + v;
            macroString += endSpontaneousComment;
        }
    }
}
